package com.zeny.coding.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zeny.coding.constants.CourseConstants;
import com.zeny.coding.dto.*;
import com.zeny.coding.enmus.CourseStatusEnum;
import com.zeny.coding.entity.*;
import com.zeny.coding.mapper.CourseMapper;
import com.zeny.coding.service.*;
import com.zeny.coding.util.SnowFlake;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <h2>课程服务</h2>
 *
 * @Author Zeny
 */
@SuppressWarnings("all")
@Service
@Slf4j
public class CourseServiceImpl implements CourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private SectionService sectionService;

    @Autowired
    private TeacherService teacherService;


    @Autowired
    private CourseCategoryService courseCategoryService;

    @Autowired
    private CourseContentFileService courseContentFileService;

    @Autowired
    private CourseContentService courseContentService;

    @Override
    public void list(PageDto<CourseDto> pageDto) {
        //分页
        PageHelper.startPage(pageDto.getPage(), pageDto.getSize());
        //设置条件
        CourseExample courseExample = new CourseExample();
        courseExample.setOrderByClause("sort asc");
        //查询结果
        List<Course> courseList = this.courseMapper.selectByExample(courseExample);
        PageInfo<Course> pageInfo = new PageInfo<>(courseList);
        //设置总条数
        pageDto.setTotal(pageInfo.getTotal());
        //封装成DTO传输
        List<CourseDto> courseDtoList = new ArrayList<>();
        for (Course course : courseList) {
            CourseDto courseDto = new CourseDto();
            BeanUtils.copyProperties(course, courseDto);
            courseDtoList.add(courseDto);
        }
        //设置记录数
        pageDto.setList(courseDtoList);
    }

    @Transactional
    @Override
    public void save(CourseDto courseDto) {
        //获取sort
        int sort = (int) this.courseMapper.countByExample(null);
        //DTO转~
        Course course = new Course();
        BeanUtils.copyProperties(courseDto, course);
        //算法算法生成ID
        SnowFlake snowFlake = new SnowFlake(
                CourseConstants.dataCenterId,
                CourseConstants.machineId);
        course.setId(String.valueOf(snowFlake.nextId()));
        course.setCreatedAt(new Date());
        course.setUpdatedAt(course.getCreatedAt());
        course.setSort(sort+1);
        this.courseMapper.insertSelective(course);
        //批量保存课程分类
        this.courseCategoryService.saveBatch(course.getId(), courseDto.getCategorys());

    }

    @Transactional
    @Override
    public void update(CourseDto courseDto) {
        Course course = new Course();
        BeanUtils.copyProperties(courseDto, course);
        this.courseMapper.updateByPrimaryKeySelective(course);
        //批量保存课程分类
        this.courseCategoryService.deleteByCourseId(course.getId());
        this.courseCategoryService.saveBatch(course.getId(), courseDto.getCategorys());
    }

    @Override
    public CourseDto findById(String id) {
        Course course = this.courseMapper.selectByPrimaryKey(id);
        CourseDto courseDto = new CourseDto();
        BeanUtils.copyProperties(course, courseDto);
        courseDto.setCategorys(this.courseCategoryService.findCategorysByCourseId(id));
        return courseDto;
    }

    @Transactional
    @Override
    public void deleteById(String id) {
        //根据课程id删除所有小节
        this.sectionService.deleteByCourseId(id);
        //跟课程id删除所有大章
        this.chapterService.deleteByCourseId(id);
        //删除所有分类
        this.courseCategoryService.deleteByCourseId(id);
        //删除课程内容
        this.courseContentService.deleteById(id);
        //删除课程文件
        this.courseContentFileService.deleteByCourseId(id);
        //更新sort
        Course course = this.courseMapper.selectByPrimaryKey(id);
        this.courseMapper.updateSortForward(course.getSort(), Integer.MAX_VALUE);
        this.courseMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    @Override
    public void updateTime(String id) {
        this.courseMapper.updateTime(id);
    }

    @Transactional
    @Override
    public void updateSort(SortDto sortDto) {
        Integer newSort = sortDto.getNewSort();
        Integer oldSort = sortDto.getOldSort();
        String courseId = sortDto.getCourseId();
        int max = (int) this.courseMapper.countByExample(null);
        if (newSort > oldSort) {
            //123456...oldSort....78 79 80 newSort
            newSort = Math.min(newSort, max);
            this.courseMapper.updateSortForward(oldSort, newSort);
        } else {
            //123456...newSort....78 79 80 oldSort
            this.courseMapper.updateSortBackward(oldSort, newSort);
        }
        this.courseMapper.updateSort(courseId, newSort);
    }

    @Override
    public List<CourseDto> list(Integer num) {
        List<Course> courseList = this.courseMapper.selectCoursesPublishNum(num);
        List<CourseDto> courseDtoList = new ArrayList<>();
        courseList.forEach(course -> {
            CourseDto courseDto = new CourseDto();
            BeanUtils.copyProperties(course, courseDto);
            courseDtoList.add(courseDto);
        });
        return courseDtoList;
    }

    @Override
    public void pageQueryByCondition(WebCoursePageDto dto) {
        //分页
        PageHelper.startPage(dto.getPage(), dto.getSize());
        //检查分类id
        String categoryId = dto.getCategoryId();
        List<Course> courses = null;
        if (StringUtils.isEmpty(categoryId)) {
            //不添加分类id条件
            CourseExample example = new CourseExample();
            //发布
            example.createCriteria().andStatusEqualTo(CourseStatusEnum.PUBLISH.getKey());
            //时间
            example.setOrderByClause("updated_at desc");
            courses = this.courseMapper.selectByExample(example);
        } else {
            //根据分类id在课程-分类、课程关联查询
            courses = this.courseMapper.findCoursesByCategoryId(categoryId);
        }
        PageInfo<Course> pageInfo = new PageInfo<>(courses);
        //设置总条数
        dto.setTotal(pageInfo.getTotal());
        //封装成DTO传输
        List<CourseDto> courseDtoList = new ArrayList<>();
        for (Course course : courses) {
            CourseDto courseDto = new CourseDto();
            BeanUtils.copyProperties(course, courseDto);
            courseDtoList.add(courseDto);
        }
        //设置记录数
        dto.setList(courseDtoList);
    }

    @Override
    public WebCourseDetailDto webCourseDetail(String id) {
        //根据id查询课程【包括课程信息，大章，小节，教师】
        Course course = this.courseMapper.selectByPrimaryKey(id);
        if (course == null || !CourseStatusEnum.PUBLISH.getKey().equals(course.getStatus())) {
            //课程状态为草稿
            log.info("该课程为Null/草稿: {}", course);
            return null;
        }
        //设置课程信息到dto
        WebCourseDetailDto webCourseDetail = new WebCourseDetailDto();
        BeanUtils.copyProperties(course, webCourseDetail);
        //查找教师信息
        TeacherDto teacher = teacherService.findById(course.getTeacherId());
        webCourseDetail.setTeacher(teacher);
        //查找大章
        List<Chapter> chapters = chapterService.findByCourseId(id);
        List<WebChapterDto> webChapters = new ArrayList<>();
        for (Chapter chapter : chapters) {
            //查找小节
            List<Section> sections = sectionService.findByChapterId(chapter.getId());
            WebChapterDto chapterDto = new WebChapterDto();
            BeanUtils.copyProperties(chapter, chapterDto);
            chapterDto.setSections(sections);
            webChapters.add(chapterDto);
        }
        webCourseDetail.setChapters(webChapters);
        //查找课程内容
        CourseContentDto contentDto = this.courseContentService.findById(id);
        webCourseDetail.setContent(contentDto.getContent());
        return webCourseDetail;
    }
}
